package com.yami.shop.api.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.bean.app.dto.MyOrderDto;
import com.yami.shop.bean.app.dto.MyOrderItemDto;
import com.yami.shop.bean.app.dto.ProductDto;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.security.api.util.SecurityUtils;
import com.yami.shop.service.MyOrderService;
import com.yami.shop.service.ProductService;
import com.yami.shop.service.UserCollectionService;
import io.swagger.v3.oas.annotations.Operation;
import org.apache.catalina.security.SecurityUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static cn.dev33.satoken.SaManager.log;

/**
 * @author DELL
 */
@RestController
@RequestMapping("/p/recommend")
public class RecommendationController {

    @Autowired
    private ProductService productService;
    @Autowired
    private UserCollectionService userCollectionService;

    // 测试接口
    @GetMapping("/test/{userId}")
    public ServerResponseEntity<String> testEndpoint(@PathVariable String userId) {
        return ServerResponseEntity.success("Hello " + userId);
    }


    @GetMapping("/user/{userId}")
    @Operation(summary = "混合推荐", description = "综合热门商品、个性化收藏和订单历史的混合推荐")
    public ServerResponseEntity<List<ProductDto>> hybridRecommend(@PathVariable("userId") String userId) {
//        String userId = SecurityUtils.getUser().getUserId();
        log.info("Received recommendation request for user: {}", userId); // 添加日志
        userId = SecurityUtils.getUser().getUserId();
        // 动态权重配置（可根据业务需求调整）
        final double BASE_HOT_WEIGHT = 0.4;
        final double COLLECTION_WEIGHT = 0.3;
        final double ORDER_WEIGHT = 0.3;

        // 1. 获取基础热门商品
        PageParam pageParam = new PageParam();

        pageParam.setSize(100);
//        List<ProductDto> hotProducts = prodService.moreBuyProdList(pageParam).getRecords();
//        IPage<ProductDto> hotProducts = productService.moreBuyProdList(pageParam);
        //2.0
        IPage<ProductDto> hotProductsPage = productService.moreBuyProdList(pageParam);
        List<ProductDto> hotProducts = hotProductsPage.getRecords(); //

//        productDtoIPage.getRecords();
        // 2. 获取用户收藏相关商品
        IPage<ProductDto> userCollectionDtoPageByUserId = productService.collectionProds(pageParam, userId);

        List<ProductDto> collectionProducts = convertCollectionsToProducts(userCollectionDtoPageByUserId.getRecords());

        // 3. 获取订单相关推荐（新增订单推荐）
        List<ProductDto> orderProducts = getOrderBasedRecommendations(userId);

        // 4. 创建综合评分映射
        Map<Long, ProductScore> productScores = new HashMap<>();



        // 填充热门商品得分
        fillHotScores(productScores, hotProducts, BASE_HOT_WEIGHT);

        // 填充收藏相关得分
        fillCollectionScores(productScores, collectionProducts, COLLECTION_WEIGHT);

        // 填充订单相关得分（新增）
        fillOrderScores(productScores, orderProducts, ORDER_WEIGHT);

        // 5. 混合排序逻辑
        List<ProductDto> finalRecommendations = mergeRecommendations(
                productScores,
                hotProducts,
                collectionProducts,
                orderProducts
        );

        // 6. 返回结果
        return ServerResponseEntity.success(finalRecommendations.stream()
                .limit(6)
                .collect(Collectors.toList()));
    }

    private List<ProductDto> convertCollectionsToProducts(List<ProductDto> collections) {
        List<Long> prodIds = collections.stream()
                .map(ProductDto::getProdId)
                .collect(Collectors.toList());
        return  productService.getProductsByIds(prodIds);
    }


    @Autowired
    private MyOrderService myOrderService;

    // 完善收藏评分方法
    private void fillCollectionScores(Map<Long, ProductScore> productScores,
                                      List<ProductDto> collectionProducts,
                                      double weight) {
        collectionProducts.forEach(p -> {
            ProductScore score = productScores.computeIfAbsent(
                    p.getProdId(),
                    k -> new ProductScore(p)
            );
            // 收藏时间加权（示例逻辑）
            score.addCollectionScore(1.0 * weight);
        });
    }

    // 新增填充热门评分方法
    private void fillHotScores(Map<Long, ProductScore> productScores,
                               List<ProductDto> hotProducts,
                               double weight) {
        // 按销量倒序排名计算得分
        int total = hotProducts.size();
        for (int i = 0; i < total; i++) {
            ProductDto product = hotProducts.get(i);
            ProductScore score = productScores.computeIfAbsent(
                    product.getProdId(),
                    k -> new ProductScore(product)
            );

            // 排名越靠前得分越高（线性衰减）
            double rankScore = 1.0 - (i * 1.0 / total);
            score.addHotScore(rankScore * weight);
        }
    }

    // 新增订单推荐逻辑
    private List<ProductDto> getOrderBasedRecommendations(String userId) {
        // 1. 获取用户近半年订单（分页查询）
        IPage<MyOrderDto> orders = myOrderService.pageMyOrderByUserIdAndStatus(
                new PageParam<MyOrderDto>().setSize(50),
                userId,
                2 // 已完成订单
        );
        // 2. 提取订单商品特征
        Set<Long> purchasedProductIds = orders.getRecords().stream()
                .flatMap(order -> order.getOrderItemDtos().stream())
                .map(MyOrderItemDto::getProdId)
                .collect(Collectors.toSet());

        // 3. 获取推荐商品（示例实现）
        if (!purchasedProductIds.isEmpty()) {
            // 策略1：推荐同类商品
            List<Long> categories = productService.getProductCategories(new ArrayList<>(purchasedProductIds));
            return productService.getProductsByCategories(categories, 10);

            // 策略2：推荐搭配商品（需实现商品关联关系）
            // return prodService.getComboProducts(purchasedProductIds);
        }
        return Collections.emptyList();
    }

    // 新增评分填充方法
    private void fillOrderScores(Map<Long, ProductScore> productScores,
                                 List<ProductDto> orderProducts,
                                 double weight) {
        orderProducts.forEach(p -> {
            ProductScore score = productScores.computeIfAbsent(
//                    p.getProductId(),
                    p.getProdId(),
                    k -> new ProductScore(p)
            );

            // 评分策略：基础分 + 时间衰减
            double timeFactor = calculateTimeDecay(p.getLatestPurchaseTime());
            score.addOrderScore(p.getRecommendationScore() * weight * timeFactor);
        });
    }

    // 时间衰减函数（近三个月购买加强推荐）
    private double calculateTimeDecay(Date purchaseTime) {
        if (purchaseTime == null) return 1.0;

        long diffDays = ChronoUnit.DAYS.between(
                purchaseTime.toInstant(),
                Instant.now()
        );
        return Math.max(0, 1 - diffDays / 90.0); // 三个月线性衰减
    }

    // 评分包装类（新增）
    private static class ProductScore {
        ProductDto product;
        double hotScore;
        double collectionScore;
        double orderScore;

        ProductScore(ProductDto product) {
            this.product = product;
        }

        void addHotScore(double score) { this.hotScore += score; }
        void addCollectionScore(double score) { this.collectionScore += score; }
        void addOrderScore(double score) { this.orderScore += score; }

        double getTotalScore() {
            return hotScore + collectionScore + orderScore;
        }
    }


    // 修正评分类
//    private static class ProductScore {
//        ProductDto product;
//        double hotScore;
//        double collectionScore;
//        double orderScore;
//
//        // 新增无参构造
//        ProductScore(ProductDto product) {
//            this.product = product;
//        }
//
//        // 新增空值保护
//        double getTotalScore() {
//            return hotScore + collectionScore + orderScore;
//        }
//    }

    // 合并推荐结果（更新后）
//    private List<ProductDto> mergeRecommendations(List<ProductDto>... sources) {
//        // 合并所有推荐源
//        List<ProductDto> allProducts = Stream.of(sources)
//                .flatMap(List::stream)
//                .collect(Collectors.toList());
//
//        // 去重并排序
//        return allProducts.stream()
//                .collect(Collectors.toMap(
//                        ProductDto::getProdId,
//                        p -> p,
//                        (p1, p2) -> p1))
//                .values()
//                .stream()
//                .sorted((p1, p2) -> Double.compare(
//                        productScores.get(p2.getProdId()).getTotalScore(),
//                        productScores.get(p1.getProdId()).getTotalScore()
//                ))
//                .collect(Collectors.toList());
//    }
// 修正合并推荐方法
    private List<ProductDto> mergeRecommendations(
            Map<Long, ProductScore> productScores,
            List<ProductDto>... sources) {

        // 合并所有商品
        List<ProductDto> allProducts = Stream.of(sources)
                .flatMap(List::stream)
                .collect(Collectors.toList());

        // 去重并排序
        return allProducts.stream()
                .collect(Collectors.toMap(
                        ProductDto::getProdId,
                        p -> p,
                        (p1, p2) -> p1))
                .values().stream()
                .sorted((p1, p2) -> Double.compare(
                        productScores.getOrDefault(p2.getProdId(), new ProductScore(p2)).getTotalScore(),
                        productScores.getOrDefault(p1.getProdId(), new ProductScore(p1)).getTotalScore()
                ))
                .collect(Collectors.toList());
    }

}
